package com.sxt;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

import com.sxt.core.regeister.Regeister;
import com.sxt.core.regeister.impl.ZkRegeisterImpl;
import com.sxt.model.Request;
import com.sxt.model.Response;

/**
 * 是有监听菜逼
 * 
 * @author Liushuangxi
 *
 */
public class ClassMate {
	public static void main(String[] args) {
		listener(100);
	}

	@SuppressWarnings("resource")
	public static void listener(int port) {
		Socket accept = null;
		ServerSocket serverSocket = null;
		InputStream inputStream = null;
		ObjectInputStream objectInputStream = null;
		OutputStream outputStream = null;
		ObjectOutputStream objectOutputStream = null;

		System.out.println("室友c-端口【" + port + "】：开始监听菜逼的问题...");
		// 注册自己
		Regeister regeister = new ZkRegeisterImpl();
		regeister.regeister("ADD", "localhost:" + port);
		System.out.println("端口【" + port + "】:注册自己成功！");
		try {
			serverSocket = new ServerSocket(port);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		while (true) {
			try {
				accept = serverSocket.accept();
				System.out.println("菜逼把问题发过来了");
				inputStream = accept.getInputStream();
				objectInputStream = new ObjectInputStream(inputStream);
				Request request = (Request) objectInputStream.readObject();

				// 解析参数
				String interfaceName = request.getInterfaceName();
				String methodName = request.getMethodName();
				// 得到真实的实现类对象
				Object realObject = getImplObject(interfaceName);
				// 得到参数类型
				Object[] args = request.getArgs();
				Class<?>[] types = new Class<?>[args.length];
				for (int i = 0; i < args.length; i++) {
					types[i] = args[i].getClass();
				}
				// 获取真实-> 获取真实对象+方法名称+方法的参数
				Method realMethod = realObject.getClass().getMethod(methodName, types);
				Object result = realMethod.invoke(realObject, args);
				Response response = new Response();
				response.setResult(result);

				outputStream = accept.getOutputStream();
				objectOutputStream = new ObjectOutputStream(outputStream);
				objectOutputStream.writeObject(response);
				objectOutputStream.flush();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				closes(objectOutputStream, outputStream, objectInputStream, inputStream, accept);
			}
		}
	}

	/**
	 * 第一来创建对象，以后每次使用个该对象 
	 * 单例：懒加载  - > ioc 的模式
	 * @param interfaceName
	 * @return
	 */
	private static Object getImplObject(String interfaceName) {
		int lastIndexOf = interfaceName.lastIndexOf(".");
		String packageName = interfaceName.substring(0, lastIndexOf); // com.sxt.service
		String classSimpleName = interfaceName.substring(lastIndexOf + 1);// AlgFunctionService
		StringBuilder sb = new StringBuilder(packageName);
		sb.append(".impl.");
		sb.append(classSimpleName);
		sb.append("Impl");
		String implClassName = sb.toString();
		Object obj = null;
		try {
			obj = Class.forName(implClassName).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * 关闭多个流的方法
	 * @param streams
	 */
	public static void closes(Closeable... streams) {
		for (Closeable closeable : streams) {
			if (closeable != null) {
				try {
					closeable.close();
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					closeable = null;
				}
			}
		}
	}
	
	public static void main1(String[] args) {
		getImplObject("com.sxt.service.AlgorithmService");
	}
}
